Treatment of Type Declarations

KCL has several runtime stacks. One of them is called the value stack which is the ``main stack'' of KCL: Arguments to functions and resulting values of functions are usually passed via the value stack, lexical variables in compiled code are usually allocated on the value stack, and temporary values during evaluation of nested expressions are usually saved on the value stack. However, if appropriate declarations are supplied to the compiler, the compiled code will use another stack called the C stack, which can be accessed more efficiently than the value stack. In addition, arguments and resulting values passed via the C stack, values of lexical variables allocated on the C stack, and temporary values saved on the C stack may sometimes be represented as raw data instead of pointers to heap-allocated cells. In KCL, even a fixnum object is usually represented as a pointer to a fixnum cell in which the raw datum (i.e., the 32-bit signed integer) for the fixnum is stored. Accessing such raw data on the C stack results in faster compiled code, partly because no pointer deferencing operation is necessary, and partly because no cell is newly allocated on the heap when a new object is created. In contrast, any object on the value stack is represented as a pointer to a heap-allocated cell.


One of the deficiencies of the use of the C stack is that raw data on the C stack may sometimes need to be reallocated on the heap. Suppose, in the following example, that the lexical variable x is allocated on the C stack and has always a fixnum raw datum as its value. (The situations in which this occurs will be explained later.)

    (defun foo ()
      (let ((x 0))
        ....
        (bar x)
        ....
        ))

Also suppose that the function bar expects its argument to be passed via the value stack rather than via the C stack. (This situation typically occurs when foo and bar are defined in separate source files. See below.) On call to bar, the compiled code of foo will allocate a fixnum cell on the heap and push the pointer to this cell on the value stack as the argument to bar.


Another deficiency is that it is sometimes dangerous to allocate a cell pointer onto the C stack. (This occurs when object declarations are supplied. See below.) The garbage collector of KCL never takes care of cell pointers on the C stack and thus a heap-allocated cell pointed to only from the C stack may be recycled for further use, while the data in the cell is still in use. This is why KCL usually uses the less efficient value stack. In contrast, objects on the value stack are automatically protected against garbage collection. Note that raw data on the C stack need not be protected against garbage collection because they remain alive until the C stack is popped.